﻿package anshe.widget
{
	import anshe.event.AnsheClientEvent;
	import anshe.event.AnsheKeyword;
	import anshe.event.AnsheNetEvent;
	import anshe.inface.IStruct;
	import anshe.inface.IWidget;
	import anshe.net.RedSharedObject;
	import anshe.struct.ActionStruct;
	import anshe.struct.AnsheGlobalStruct;
	import anshe.struct.game.GGameData;
	import anshe.struct.game.GRoomInfo;
	import anshe.struct.game.GUserInfo;
	
	import kiss.event.globalEvent;
	
	public class AnsheClient extends AnsheSuperClient
	{
		protected var gameSO:RedSharedObject;	//	游戏的 SharedObject 对象
		protected var roomSO:RedSharedObject;	//	游戏房间的 SharedObject 对象
		
		protected var roomArray:Array;		//	房间列表（列表内全部是 GRoomInfo 类及子类对象）
		protected var userArray:Array;		//	用户列表（列表内全部是 GUserInfo 类及子类对象）
		protected var gameArray:Array;		//	游戏数据列表（列表内全部是 GGameInfo 类及子类对象）
		protected var isFree:Boolean;		//	是否免费游戏
		
		private var swfFileName:String;		//	当前对象对应的 SWF 文件名称
		
		private var widget:IWidget;		//	游戏主体对象

		public function AnsheClient(gName:String, swfName:String, gWidget:IWidget)
		{
			super(gName);
						
			this.cacheAsBitmap = true;

			swfFileName = swfName;
			widget = gWidget;
			
			roomArray = new Array();
			userArray = new Array();
			gameArray = new Array();		
		}
		
		//-------------------------------------------------------------------------------------
		//	以下为一些在基类中需要封装好的操作方法
		//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  - - - - - -
		//		JoinGame(...argc)			initGame 方法，向服务器注册游戏
		//		UpdataRoomInfo(...argc)		updataRoomInfo 方法，向服务器申请变更房间信息
		//		UpdataPlayerInfo(...argc)	updataPlayerInfo 方法，向服务器申请变更房间内玩家信息
		//		UpdataGameData(...argc)		updataGameInfo 方法，向服务器申请更新房间内游戏信息
		//
		//		RushRoomInfo(...argc)		刷新游戏房间列表
		//		RushUserInfo(...argc)		刷新游戏房间内用户列表
		//		RushGameData(...argc)		刷新游戏房间内指定用户的游戏信息
		//-------------------------------------------------------------------------------------
		
		//	加入游戏
		public function JoinGame(...argc):void
		{
			ShowMessage("Start Join Game");
			
			var gObj:AnsheGlobalStruct = new AnsheGlobalStruct(this.gameName);
			
			this.userArray = gObj.userArray;
			this.roomArray = gObj.roomArray;
			this.gameArray = gObj.gameArray;
			this.roomSO = gObj.roomSO;
			this.gameSO = gObj.gameSO;
			
			var act:ActionStruct = new ActionStruct(msgArray.length);
			act.actClient = this;
			act.actString = AnsheKeyword.LOGIN_GAME;
			act.actFunction = "onJoinDone";
			act.isGlobal = true;

			try
			{
				if(this.space.userInfo)
				{
					act.actData = new Array(gameName, this.space.userInfo.userFace).concat(argc);
				}
				else
				{
					act.actData = new Array(gameName).concat(argc);
				}
			}
			catch(e:*)
			{
				ShowMessage("Can't find WidgetSpace by initGame");
				act.actData = new Array(gameName).concat(argc);
			}
			
			msgArray.push(act);
		}
		
		public final function onJoinDone(argc:Array):void
		{
			ShowMessage("注册游戏成功!!");

			this.dispatchEvent(new AnsheClientEvent(AnsheClientEvent.JOIN_GAME_DONE, argc));
			
			try
			{
				CreateGameSO(argc[0]);
				
				var tArray:Array = argc[1];
				for(var i:int = 0; i < tArray.length; i++)
				{
					AddRoomInfo(tArray[i]);
				}	
				
				if(argc.length >= 3)
				{
					this.isFree = Boolean(argc[2]);
				}			
				
				this.dispatchEvent(new AnsheClientEvent(AnsheClientEvent.UPDATA_ROOM_INFO));
			}
			catch(e:*)
			{
				ShowMessage("分析房间信息时出错:" + e);
			}
		}
				
		//	检测房间是否重复
		private function CheckRoom(id:Number):Boolean
		{
			return !Boolean(GetRoomByID(id) == null);
		}
		
		//	检测用户是否重复
		private function CheckPlayer(id:String):Boolean
		{
			return !Boolean(GetPlayerByID(id) == null);
		}
		
		//	根据房间 ID 号取到一个房间
		protected function GetRoomByID(rID:Number):IStruct
		{
			for(var i:int = 0; i < this.roomArray.length; i++)
			{
				var rInfo:IStruct = this.roomArray[i];
				if(GRoomInfo(rInfo).roomID == rID)
				{
					return rInfo;
				}
			}
			return null;
		}
		
		//	根据用户 IMVU_ID 号搜索一个用户信息
		protected function GetPlayerByID(pID:String):IStruct
		{
			ShowMessage("传入的用户ID是:" + pID);
			for(var i:int = 0; i < this.userArray.length; i++)
			{
				var rInfo:IStruct = this.userArray[i];
				if(GUserInfo(rInfo).userID == pID)
				{
					ShowMessage("找到该用户了");
					return rInfo;
				}
			}
			return null;
		}
		
		//	根据用户 ID 号搜索一个游戏信息
		protected function GetGameDataByID(pID:String):IStruct
		{
			ShowMessage("传入的游戏ID是:" + pID);
			for(var i:int = 0; i < this.gameArray.length; i++)
			{
				var rInfo:IStruct = this.gameArray[i];
				if(GGameData(rInfo).playerID == pID)
				{
					ShowMessage("找到该用户了");
					return rInfo;
				}
			}
			return null;
		}

		
		//	删除当前影片
		public function RemoveThisGame():void
		{			
			try
			{
				DeleteListener();
								
				try
				{
					if(this.space)
					{
						if(this.space.gameArray)
						{
							for(var i:int = 0; i < this.space.gameArray.length; i++)
							{
								var str:String = this.space.gameArray[i];
								if(str)
								{
									trace("find swfName::" + this.swfFileName + " --> " + str);
									if(str.toLowerCase().indexOf(this.swfFileName.toLowerCase()) >= 0)
									{
										delete this.space.gameArray[i];
									}
								}
							}
						}
					}
				}
				catch(e:*)
				{
					ShowMessage("Delete Movie Error::" + e);
				}
				
				// this.stage.dispatchEvent(new globalEvent(globalEvent.CLOSEFLASH, this.gameName + ".swf"));
				this.parent.removeChild(this);
			}
			catch(e:*)
			{
				ShowMessage("Delete Movie Error By Space:: " + e);
				this.parent.removeChild(this);
			}
		}
		
		//	通知服务器，更新房间及游戏规则信息（传入参数为房间信息相关的变量列表，该列表由服务器端客户端共同约定）
		public function UpdataRoomInfo(...argc):void
		{
			var act:ActionStruct = new ActionStruct(msgArray.length);
			act.actClient = this;
			act.actString = AnsheKeyword.RUSH_G_ROOM;
			act.actFunction = "onRushError";
			act.actData = argc;
			
			msgArray.push(act);
		}

		//	通知服务器，更新房间内游戏玩家信息（传入参数为房间信息相关的变量列表，该列表由服务器端客户端共同约定）
		public function UpdataPlayerInfo(...argc):void
		{
			var act:ActionStruct = new ActionStruct(msgArray.length);
			act.actClient = this;
			act.actString = AnsheKeyword.RUSH_G_PLAYER;
			act.actFunction = "onRushError";
			act.actData = argc;
			
			msgArray.push(act);
		}

		//	通知服务器，更新房间内游戏数据信息（传入参数为房间信息相关的变量列表，该列表由服务器端客户端共同约定）
		public function UpdataGameData(...argc):void
		{
			var act:ActionStruct = new ActionStruct(msgArray.length);
			act.actClient = this;
			act.actString = AnsheKeyword.RUSH_G_GAMEDATA;
			act.actFunction = "onRushError";
			act.actData = argc;
			
			msgArray.push(act);
		}
		
		//	当 initGame 调用成功后触发
		public function InitGameData(...argc):void
		{
			//ShowMessage("InitGameData 取得数据：：", argc);
			// traceObject(argc);
		}
		
		//	刷新 游戏房间 的信息
		public function RushRoomInfo(...argc):void
		{
			//ShowMessage("RushRoomInfo 取得数据：：", argc);
			var rInfo:IStruct = AddRoomInfo(argc[1]);
			this.dispatchEvent(new AnsheClientEvent(AnsheClientEvent.UPDATA_ROOM_INFO, rInfo));
		}
		
		//	刷新 游戏房间内用户 的信息
		public function RushUserInfo(...argc):void
		{
			// ShowMessage("RushUserInfo 取得数据：：", argc);
			// trace("收到信息,更新一次用户信息");
			// traceObject(argc);
			var pInfo:IStruct = AddPlayerInfo(argc[1]);
			this.dispatchEvent(new AnsheClientEvent(AnsheClientEvent.UPDATA_PLAYER_INFO, pInfo));
		}
		
		//	刷新 游戏中用户的游戏数据 的信息
		public function RushGameData(...argc):void
		{
			//ShowMessage("RushGameData 取得数据：：", argc);
			// traceObject(argc);
			var pInfo:IStruct = AddGameData(argc[1]);
			this.dispatchEvent(new AnsheClientEvent(AnsheClientEvent.UPDATA_GAME_DATA, pInfo));
		}
		
		//	显示数据时使用
		protected function traceObject(array:Array):void
		{
			try
			{
				ShowMessage("显示数组中的数据,数组长度为 : " + array.length);
				
				for(var i:int = 0; i < array.length; i++)
				{
					ShowMessage("现在显示第 " + i + " 条数据");
					var obj:Object = array[i];
					for(var o:* in obj)
					{
						ShowMessage(" --> " + o + " : " + obj[o]);
					}
				}
			}
			catch(e:*)
			{
				ShowMessage("分析数组内容时出错:",e);
			}
		}
		
		//	追加一个新房间（如果房间已经存在，则更新房间信息）
		protected final function AddRoomInfo(data:Object):IStruct
		{
			var rInfo:IStruct = GetRoomByID((new GRoomInfo().fromObject(data) as GRoomInfo).roomID);
			
			if(rInfo)
			{
				rInfo = widget.GetGameRoomInfo(data);
				for(var i:int = 0; i < this.roomArray.length; i++)
				{
					if((this.roomArray[i] as GRoomInfo).roomID == (rInfo as GRoomInfo).roomID)
					{
						// this.ShowMessage("修改房间数组中的数据项");
						this.roomArray[i] = rInfo;
						return rInfo;
					}
				}

			}
			else
			{
				rInfo = widget.GetGameRoomInfo(data);
				this.roomArray.push(rInfo);
				return rInfo;
			}
			return null;
		}
		
		//	追加一个新用户（如果用户已经存在，则更新用户信息）
		protected final function AddPlayerInfo(data:Object):IStruct
		{
			ShowMessage("现在追加一条用户记录:");
			
			var rInfo:IStruct = GetPlayerByID((new GUserInfo().fromObject(data) as GUserInfo).userID);
			
			if(rInfo)
			{				
				rInfo = widget.GetGamePlayerInfo(data);
				for(var i:int = 0; i < this.userArray.length; i++)
				{
					if((this.userArray[i] as GUserInfo).userID == (rInfo as GUserInfo).userID)
					{
						// this.ShowMessage("修改用户数组中的数据项");
						this.userArray[i] = rInfo;
						return rInfo;
					}
				}
				ShowMessage("更新旧有的用户数据,当前数据为:\n" + rInfo);
			}
			else
			{
				rInfo = widget.GetGamePlayerInfo(data);
				this.userArray.push(rInfo);
				return rInfo;
				ShowMessage("添加新用户数据,当前数据为:\n" + rInfo);
			}
			ShowMessage("现在重新显示一下用户列表中的数据项:\n");
			for(var j:int = 0; j < this.userArray.length; j++)
			{
				var uInfo:IStruct = this.userArray[j];
				this.ShowMessage("第 " + j + " 个用户: \n" + uInfo);
			}
			return null;
		}

		//	追加一个新用户（如果用户已经存在，则更新用户信息）
		protected final function AddGameData(data:Object):IStruct
		{
			ShowMessage("现在追加一条游戏记录:");
			
			var rInfo:IStruct = this.GetGameDataByID((new GGameData().fromObject(data) as GGameData).playerID);
			
			if(rInfo)
			{				
				rInfo = widget.GetGameDataInfo(data);
				for(var i:int = 0; i < this.gameArray.length; i++)
				{
					if((this.gameArray[i] as GGameData).playerID == (rInfo as GGameData).playerID)
					{
						// this.ShowMessage("修改用户数组中的数据项");
						this.gameArray[i] = rInfo;
						return rInfo;
					}
				}
				// ShowMessage("更新旧有的用户数据,当前数据为:\n" + rInfo);
			}
			else
			{
				rInfo = widget.GetGameDataInfo(data);
				this.gameArray.push(rInfo);
				return rInfo;
				// ShowMessage("添加新用户数据,当前数据为:\n" + rInfo);
			}
			return null;
			//ShowMessage("现在重新显示一下游戏列表中的数据项:\n");
			//for(var j:int = 0; j < this.gameArray.length; j++)
			//{
			//	var gInfo:IStruct = this.gameArray[j];
			//	this.ShowMessage("第 " + j + " 条游戏数据: \n" + gInfo);
			//}
		}

		//---------------------------------------------------------------
		
		protected override function InitGame():void
		{
			super.InitGame();
			
			this.space = AnsheGlobal.GetAcsSprite(this);
			
			trace("Start Get Space by AnsheClient " + this.space + " ");

			ShowMessage("InitGame Done!!! [" + this.space + "]");
		}
		
		//	删除所有的事件侦听函数
		protected function DeleteListener():void
		{	
			if(this.roomSO)
			{
				this.roomSO.close();
			}
			if(this.gameSO)
			{
				this.gameSO.close();
			}
		}
		
		/**
		//	传入一个 Object 类对象，返回一个 IStruct 结构类成员（该方法必须由子类重写）
		protected function GetGameRoomInfo(obj:Object):IStruct
		{
			return new GRoomInfo().fromObject(obj);
		}
		
		//	传入一个 Object 类对象，返回一个 IStruct 结构类成员（该方法必须由子类重写）
		protected function GetGamePlayerInfo(obj:Object):IStruct
		{
			return new GUserInfo().fromObject(obj);
		}

		//	传入一个 Object 类对象，返回一个 IStruct 结构类成员（该方法必须由子类重写）
		protected function GetGameDataInfo(obj:Object):IStruct
		{
			return new GGameData().fromObject(obj);
		}
		//**/
		
		//	创建房间游戏 SharedObject 类对象实例
		protected final function CreateGameSO(soName:String):void
		{
			try
			{
				ShowMessage("开始连接 SO ：" + soName);
				
				gameSO = new RedSharedObject();
				gameSO.addEventListener(AnsheNetEvent.SO_RUSH_DATA, onGameSoLinkDone);
				gameSO.connect(soName, this.server.nc);
			}
			catch(err:*)
			{
				ShowMessage("创建游戏 SO 时出错");
			}
		}
		
		//	创建房间 SO
		protected final function CreateRoomSO(soName:String):void
		{
			try
			{
				if(this.roomSO)
				{
					this.roomSO.removeEventListener(AnsheNetEvent.SO_RUSH_DATA, onGRoomSoLinkDone);
				}
				
				roomSO = new RedSharedObject();
				roomSO.addEventListener(AnsheNetEvent.SO_RUSH_DATA, onGRoomSoLinkDone);
				roomSO.connect(soName, this.server.nc);
			}
			catch(e:*)
			{
				ShowMessage("创建游戏房间 SO 时出错");
			}
		}
		
		//-----------------------------------------------------------------------------
		
		private function onGameSoLinkDone(e:AnsheNetEvent):void
		{
			this.gameSO.client = this;
			
			ShowMessage("连接游戏 SharedObject 成功 :: " + e.data);
		}

		private function onGRoomSoLinkDone(e:AnsheNetEvent):void
		{
			this.roomSO.client = this;
			
			ShowMessage("连接游戏房间内 SharedObject 成功 :: " + e.data);
		}
	}
}